package web.error;

import framework.config.ErrorConfig;
import framework.exceptions.BusinessException;
import framework.exceptions.NotFoundException;
import framework.exceptions.WebException;
import framework.utils.RequestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;

@ControllerAdvice
public class SysErrorAdviceHandler {

    @Autowired
    private ErrorConfig errorConfig;

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ModelAndView requestParameterException(MissingServletRequestParameterException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String message = RequestUtil.getMessageDefault("sys.request.parameter.invalid", "Request parameter {0} invalid", e.getParameterName());
        return SysErrorHandler.handleException(this.errorConfig, new BusinessException(message, e), request, response);
    }

    @ExceptionHandler({BindException.class})
    public ModelAndView requestModelParameterException(BindException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String message;
        if (e.hasFieldErrors()) {
            message = RequestUtil.getMessageDefault("sys.request.parameter.invalid", "Request parameter {0} invalid", e.getFieldError().getField());
        } else {
            message = e.getMessage();
        }
        return SysErrorHandler.handleException(this.errorConfig, new BusinessException(message, e), request, response);
    }

    @ExceptionHandler({DuplicateKeyException.class})
    public ModelAndView sqlDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String message = RequestUtil.getMessageDefault("duplicateKeyError", "Duplicate name or key error: {0}", e.getMessage());
        return SysErrorHandler.handleException(this.errorConfig, new BusinessException(message, e), request, response);
    }

    @ExceptionHandler({FileNotFoundException.class, NotFoundException.class})
    public ModelAndView handle(FileNotFoundException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        return SysErrorHandler.handleException(this.errorConfig, e, request, response);
    }

    @ExceptionHandler({WebException.class})
    public ModelAndView handle(WebException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        return SysErrorHandler.handleException(this.errorConfig, e, request, response);
    }

    @ExceptionHandler({BusinessException.class})
    public ModelAndView businessException(BusinessException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        return SysErrorHandler.handleException(this.errorConfig, e, request, response);
    }

}
